﻿#include "function_segment_circle.h"


// Procedures
void segmentCicle (HObject ho_image, HObject *ho_image_crop, HTuple hv_inner_radius,
    HTuple hv_outer_radius, HTuple *hv_ret)
{

  // Local iconic variables
  HObject  ho_RegionTop, ho_RegionClosingTop, ho_ConnectedRegions;
  HObject  ho_SelectedRegions, ho_Contours, ho_CircleOut, ho_Circleinner;
  HObject  ho_RegionDifference, ho_ImageReduced;

  // Local control variables
  HTuple  hv_UsedThreshold, hv_row, hv_column, hv_radius;
  HTuple  hv_StartPhi, hv_EndPhi, hv_PointOrder;

  BinaryThreshold(ho_image, &ho_RegionTop, "max_separability", "dark", &hv_UsedThreshold);
  ClosingCircle(ho_RegionTop, &ho_RegionClosingTop, 15.5);
  Connection(ho_RegionClosingTop, &ho_ConnectedRegions);
  SelectShapeStd(ho_ConnectedRegions, &ho_SelectedRegions, "max_area", 70);

  GenContourRegionXld(ho_SelectedRegions, &ho_Contours, "border");

  FitCircleContourXld(ho_Contours, "algebraic", -1, 0, 0, 3, 2, &hv_row, &hv_column,
      &hv_radius, &hv_StartPhi, &hv_EndPhi, &hv_PointOrder);
  GenCircle(&ho_CircleOut, hv_row, hv_column, hv_outer_radius);
  GenCircle(&ho_Circleinner, hv_row, hv_column, hv_inner_radius);
  Difference(ho_CircleOut, ho_Circleinner, &ho_RegionDifference);
  ReduceDomain(ho_image, ho_RegionDifference, &ho_ImageReduced);
  CropDomain(ho_ImageReduced, &(*ho_image_crop));
  (*hv_ret) = 1;
  return;
}


FunctionSegmentCircle::FunctionSegmentCircle(QDialog* parent, QSettings* qsettings, QString section) : QDialog(parent)
{
    m_qsettings = qsettings;
    m_section = section;

    this->setWindowTitle(("SegmentCircle"));
    QRect desktop_rect = QApplication::desktop()->geometry();
    double ratio_x = desktop_rect.width()/1920.0;
    double ratio_y = desktop_rect.height()/1080.0;

    move(0,0);
    setFixedSize(1920*ratio_x,1010*ratio_y);

	QHBoxLayout* hlayout = new QHBoxLayout();
	this->setLayout(hlayout);

    QSize control_size(220*ratio_x,40*ratio_y);

    QWidget* p = new QWidget(this);
    p->move(0*ratio_x,0*ratio_y);
    p->setFixedSize(600*ratio_x,800*ratio_y);
	hlayout->addWidget(p);

    QGridLayout *qgridLayout = new QGridLayout();
    p->setLayout(qgridLayout);

    int index =0;
    m_qlabel_inner_radius = new QLabel();
    m_qlabel_inner_radius->setText("RadiusMin");
    m_qlabel_inner_radius->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_inner_radius, index, 0);

    m_qspinbox_inner_radius = new QSpinBox();
    m_qspinbox_inner_radius->setFixedSize(control_size);
    m_qspinbox_inner_radius->setMinimum(0);
    m_qspinbox_inner_radius->setMaximum(2000);
    qgridLayout->addWidget(m_qspinbox_inner_radius, index, 1);
    index++;

    m_qlabel_outer_radius = new QLabel();
    m_qlabel_outer_radius->setText("RadiusMax");
    m_qlabel_outer_radius->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_outer_radius, index, 0);


    m_qspinbox_outer_radius = new QSpinBox();
    m_qspinbox_outer_radius->setFixedSize(control_size);
    m_qspinbox_outer_radius->setMinimum(0);
    m_qspinbox_outer_radius->setMaximum(2000);
    qgridLayout->addWidget(m_qspinbox_outer_radius, index, 1);
    index++;

    m_pushbutton_save_parameter = new QPushButton(this);
    m_pushbutton_save_parameter->setFixedSize(control_size);
    m_pushbutton_save_parameter->setText("Save");
    connect(m_pushbutton_save_parameter, &QPushButton::clicked, this, &FunctionSegmentCircle::saveParameter);
    qgridLayout->addWidget(m_pushbutton_save_parameter, index,0);

	m_pushbutton_dir_crop = new QPushButton(this);
	m_pushbutton_dir_crop->setFixedSize(control_size);
	m_pushbutton_dir_crop->setText("AutoCrop");
	connect(m_pushbutton_dir_crop, &QPushButton::clicked, this, [=]() {
		QString directory;

		directory = QFileDialog::getExistingDirectory(this,
			tr("select dir"),
			"");
		if (directory.isEmpty())
		{
			return;
		}

		QDir dir(directory);
		dir.setFilter(QDir::Files | QDir::NoSymLinks);
		QStringList filters;
		filters << "*.bmp" << "*.jpg" << "*.png";
		dir.setNameFilters(filters);


		QString dir_sub = directory + "/crop";
		if (!dir.exists(dir_sub))
		{
			dir.mkpath(dir_sub);
		}

		QStringList  string_list = dir.entryList();
		/*QStringList string_list_path;
		foreach(QString  var, string_list) {
			string_list_path << dir_sub + "/" + var;
		}*/


		foreach(QString  var, string_list) {



			Mat mat_image = imread((directory + "/" + var).toLocal8Bit().toStdString().c_str(), -1);

			if (mat_image.empty())
			{
				QMessageBox::information(nullptr, "", "no image");
				return;
			}
			HObject image = matToHImage(mat_image);



			QString msg;
			detection(image, msg);

			Mat mat_image_crop = himageToMat(image_crop);
			imwrite((directory + "/crop/" + var).toLocal8Bit().toStdString().c_str(), mat_image_crop);



		}


	});
	qgridLayout->addWidget(m_pushbutton_dir_crop, index, 1);

    index++;
	m_pushbutton_show_orign_image = new QPushButton(this);
	m_pushbutton_show_orign_image->setFixedSize(control_size);
    m_pushbutton_show_orign_image->setText("ShowOrign");
	connect(m_pushbutton_show_orign_image, &QPushButton::clicked, this, [=]() {
		QImage q_image = matToQImage(m_image);
		m_view->setImage(q_image, "");
		return true;
	});
	qgridLayout->addWidget(m_pushbutton_show_orign_image, index, 0);



	index++;
	m_pushbutton_detection = new QPushButton(this);
	m_pushbutton_detection->setFixedSize(control_size);
    m_pushbutton_detection->setText("Detection");
    connect(m_pushbutton_detection, &QPushButton::clicked, this, &FunctionSegmentCircle::detectionImage);
	qgridLayout->addWidget(m_pushbutton_detection, index, 1);
    
    index++;
    m_pushbutton_return = new QPushButton(this);
    m_pushbutton_return->setFixedSize(control_size);
    m_pushbutton_return->setText("Exit");
    qgridLayout->addWidget(m_pushbutton_return, index, 0);
    connect(m_pushbutton_return, &QPushButton::clicked, this, [=]() {
        this->hide();
        });
	

	QVBoxLayout* view_layout = new QVBoxLayout();
	view_layout->setMargin(0);
	m_view = new QtQGraphicsView(this);
	m_view->setFixedSize(1250 * ratio_x, 900 * ratio_y);
	view_layout->addWidget(m_view);
	QLabel* m_view_pixel_qlabel = new QLabel(this);
	m_view_pixel_qlabel->setAlignment(Qt::AlignRight);
	m_view_pixel_qlabel->setText("");
	m_view_pixel_qlabel->setFixedSize(1250 * ratio_x, 20 * ratio_y);
	view_layout->addWidget(m_view_pixel_qlabel);
	hlayout->addLayout(view_layout);

	connect(m_view->m_pixmapItem, &QtQGraphicsPixmapItem::sendMessage, this, [=](QPointF pos, QString message)
	{
		m_view_pixel_qlabel->setText(message);
	});


    loadParameter();
}

FunctionSegmentCircle::~FunctionSegmentCircle()
{
    ;
}

bool FunctionSegmentCircle::detection( HObject image_in, QString& message)
{
    try
    {
		HTuple hv_max_value, hv_ret;
        segmentCicle(image_in, &image_crop, m_inner_radius,m_outer_radius,&hv_ret);

		

		int ret = hv_ret[0].I();
		
		if(ret>0)
		{
			return true;
        }
        else
        {

            message = "NG ai segment";
            return false;
        }
    }
	catch (HException &HDevExpDefaultException)
	{
		message = HDevExpDefaultException.ErrorMessage();
		return false;
	}
  
    return true;
}

void FunctionSegmentCircle::detectionImage()
{
    if(m_image.empty())
    {
        QMessageBox::information(nullptr,"","no image");
        return;
    }

    QString message;
    HObject image = matToHImage(m_image);
    bool state = detection(image, message);

    Mat image_show = m_image.clone();
    if(image_show.empty())
    {
        QMessageBox::information(nullptr,"","no image");
        return;
    }
    draw(image_show, image_show);

    QImage q_image = matToQImage(image_show);

    m_view->setImage(q_image, message);
    
    }

void FunctionSegmentCircle::draw(Mat image_in,Mat& image_out)
{
	if (image_crop.IsInitialized()){
		image_out = himageToMat(image_crop);
		image_crop.Clear();
	}
	else
	{
		image_out = image_in;
	}
}

void FunctionSegmentCircle::loadParameter()
{
    m_inner_radius   = m_qsettings->value(m_section + "/" + "m_inner_radius").toInt();
    m_outer_radius   = m_qsettings->value(m_section + "/" + "m_outer_radius").toInt();

    m_qspinbox_inner_radius->setValue(m_inner_radius);
    m_qspinbox_outer_radius->setValue(m_outer_radius);
    return ;
}

void FunctionSegmentCircle::saveParameter()
{
    m_inner_radius  = m_qspinbox_inner_radius->value();
    m_outer_radius  = m_qspinbox_outer_radius->value();
    m_qsettings->setValue(m_section + "/" + "m_inner_radius", m_inner_radius);
    m_qsettings->setValue(m_section + "/" + "m_outer_radius", m_outer_radius);
    return;
}

bool FunctionSegmentCircle::showDialog()
{
    QImage q_image = matToQImage(m_image);
    m_view->setImage(q_image, "");
   
    return true;
}


